昨天有講一個古老的設計:利用標頭檔將類別介面與實作拆開並預先編譯用以隱藏實作細節但還是不夠安全隱密,因為從標頭檔還是可以看到private的資料成員與方法成員,這時可用proxy class代理類別進一步隱藏來看看這好玩的範例。
第一個文件Implementation.h(10.24)中有我們要隱藏的原始碼,第二個文件Interface.h(10.25)包含proxy class的介面,要注意的是有兩段分別是class Implementation;定義一個Implementation類別,並在private底下宣告一個Implementation類別的指標,第三個文件Interface.cpp(10.26)是proxy class的實作,值得注意的是不僅include了Interface的介面也include了Implementation的程式碼細節。
最後一個文件fig10_27.cpp就是精隨了只include了Interface.h就是代理物件的介面,原始的Implementation類別被徹底隱藏,接著在main()中就是一般的Interface物件方法的操作.getValue()與.setValue(),因為有解構式的存在就不用手動delete回收物件。講完了不知大家有沒有覺得C++真簡單,話說那麼簡單的語言絕對不能只有我學過,我已經成功拉一個成大經濟系的學第入坑了比老鼠會還邪惡ㄏㄏ。
class Implementation
{
public:
// constructor
Implementation( int v )
: value( v ) // initialize value with v
{
// empty body
} // end constructor Implementation
void setValue( int v )
{
value = v; // should validate v
} // end function setValue
int getValue() const {
return value;
} // end function getValue
private:
int value; // data that we would like to hide from the client
}; // end class Implementation
// Client sees this source code, but the source code does not reveal
// the data layout of class Implementation.
class Implementation; // forward class declaration required by line 17
class Interface
{
public:
Interface( int ); // constructor
void setValue( int ); // same public interface as
int getValue() const; // class Implementation has
~Interface(); // destructor
private:
// requires previous forward declaration (line 6)
Implementation *ptr;
}; // end class Interface
// Implementation of class Interface--client receives this file only
// as precompiled object code, keeping the implementation hidden.
#include "Interface.h" // Interface class definition
#include "Implementation.h" // Implementation class definition
// constructor
Interface::Interface( int v )
: ptr ( new Implementation( v ) ) // initialize ptr to point to
{ // a new Implementation object
// empty body
} // end Interface constructor
// call Implementation's setValue function
void Interface::setValue( int v )
{
ptr->setValue( v );
} // end function setValue
// call Implementation's getValue function
int Interface::getValue() const
{
return ptr->getValue();
} // end function getValue
// destructor
Interface::~Interface()
{
delete ptr;
} // end ~Interface destructor
// Hiding a class’s private data with a proxy class.
#include <iostream>
using std::cout;
using std::endl;
#include "Interface.h" // Interface class definition
int main()
{
Interface i( 5 ); // create Interface object
cout << "Interface contains: " << i.getValue()
<< " before setValue" << endl;
i.setValue( 10 );
cout << "Interface contains: " << i.getValue()
<< " after setValue" << endl;
return 0;
} // end main